<template>
  <div id="player"></div>
</template>

<script lang="ts">
import { OnEvent } from "@/acUtils/OnEvent";
import { OnReady } from "@/acUtils/OnReady";
import { onBeforeUnmount, onMounted } from "vue";
import { ManageCommand } from "./AcType";
export default {
  setup(props: any, context: any) {
    // 登录后获得的权限对象
    let authorization: any = null;
    // 场景的WebSocket
    let webSocket: WebSocket | null = null;
    let player: { destroy: () => void } | null = null;
    let playerApi: { destroy: () => any } | null = null;
    /**
     * @description: 设置PlayerSize为windowSize
     * @author: zwj
     * @param {*}
     * @return {*}
     */
    const setPlayerOfWindowSize = () => {
      const player = document.getElementById("player");
      player && (player.style.height = window.innerHeight - 56 + "px");
      player && (player.style.width = window.innerWidth + "px");
    };
    /**
     * @description: 获取WebSocketUrl地址
     * @author: zwj
     * @param {*}
     * @return {*}
     */
    const getWebSocketURL = (): string => {
      return `ws://${window.HostConfig.Manager}`;
    };
    /**
     * @description: 连接AirCity实例
     * @author: zwj
     * @param {Boolean} isCloud 是否是Cloud，如果是explorer则传false，其用途是判断是否使用视频流的信息传输
     * @param {*} sceneId 场景id
     * @return {*}
     */
    const connectionAcScene = (isCloud: boolean, sceneId: any) => {
      // AirCityAPI初始化选项
      const apiOptions = {
        onReady: OnReady,
        onApiVersion: (e: any) => {
          //
        },
        onEvent: OnEvent,
        onLog: (e: any) => {
          //
        },
        useColorLog: false, //仅用于SDK测试页面，二次开发请设置为false,设置为false了Ac的错误log就打印不出来了，因此上面的log函数也不执行
      };
      // Cloud需要同时初始化AirCityAPI和AirCityPlayer
      if (isCloud) {
        let acPlayerOption: any;
        const playerEle = document.getElementById("player");
        if (playerEle) {
          acPlayerOption = {
            iid: sceneId, //如果想连接指定的云渲染实例，可以指定这个参数
            pid: null,
            domId: "player",
            apiOptions,
            showMarker: false,
            showStartupInfo: false,
            onclose: (e: any) => {
              //如果没有指定工程文件，则加上pid参数，pid=-1让服务器随便指定一个工程文件
              //如果想访问指定的工程文件，则明确指定pid, 例如pid=3
              if (e && e.code == 4009) {
                if (location.href.indexOf("?") == -1)
                  location.href += "?pid=-1";
                else location.href += "&pid=-1";
              }
            },
          };
        } else {
          acPlayerOption = {
            iid: sceneId,
            pid: null,
            apiOptions,
          };
        }
        // 这个就是整个视频流场景
        const airCityPlayer: any = new window.AirCityPlayer(
          window.HostConfig.Player,
          acPlayerOption
        );
        // 设置当前player实例用于在beforeDestory时把实例销毁掉
        player = airCityPlayer;
        // __g
        const airCityApi = airCityPlayer.getAPI();
        // 设置当前api实例用于在beforeDestory时把api销毁掉
        playerApi = airCityApi;
      } else {
        // 在explorer中只需要有__g
        const airCityApi: any = new window.AirCityAPI(
          window.HostConfig.Player,
          apiOptions
        );
        // 设置当前api实例用于在beforeDestory时把api销毁掉
        playerApi = airCityApi;
      }
    };
    /**
     * @description: 发送webSocket信息
     * @author: zwj
     * @param {*}
     * @return {*}
     */
    const sendWebSocketData = (sendInfoObj: any) => {
      // 5.0集群版cloud需要在发送之前需要附加上授权信息以进行权限验证
      if (authorization) {
        sendInfoObj.authorization = authorization;
      }
      webSocket && webSocket.send(JSON.stringify(sendInfoObj));
    };
    /**
     * @description: 重置场景
     * @author: zwj
     * @param {*}
     * @return {*}
     */
    const resetScene = () => {
      window.__g.reset();
    };
    /**
     * @description: 连接AirCityWebSocket成功了自动会调用连接AirCity
     * @author: zwj
     * @param {*}
     * @return {*}
     */
    const connectWebSocket = () => {
      const webSocketUrl: string = getWebSocketURL();
      webSocket = new WebSocket(webSocketUrl);
      // 当WebSocket连接成功
      webSocket.onopen = () => {
        console.log("%c WebSocket连接成功!", "color: #66ccff");
        // 发送AirCity登录信息
        sendWebSocketData({
          command: ManageCommand.Login,
          userName: window.userInfo ? window.userInfo.UserName : "admin",
          password: window.userInfo ? window.userInfo.PassWord : "admin",
        });
      };
      webSocket.onmessage = (e) => {
        // 登录响应的信息
        const loginResponseInfo = JSON.parse(e.data);
        // 查看登录的响应信息显示是否登录过期
        if (loginResponseInfo.result === 1) {
          console.log(
            "%c 登录失败或者登录信息已过期，请重新登录!",
            "color: #66ccff"
          );
          return;
        }
        switch (loginResponseInfo.command) {
          case -1:
            if (loginResponseInfo.result === 0) {
              authorization = loginResponseInfo.authorization; // 保存返回回来的授权信息
              console.log("%c 登录成功", "color: #66ccff");
              // 登录成功获取空闲实例
              sendWebSocketData({
                command: ManageCommand.GetOneFreeInstanceRunning,
                details: true,
                connections: true,
              });
            }
            break;
          case 103:
            // 这里的返回是获取到空闲实例（或者正在运行的实例）,在这里进行实例的连接
            // loginResponseInfo:这里其实就不是登录信息返回回来的东西了，这是登录信息之后返回回来的信息也就是当前空闲实例场景的信息
            connectionAcScene(true, loginResponseInfo.id);
            // 场景resize重置playerSize
            window.addEventListener("resize", setPlayerOfWindowSize);
            // 场景刷新前重置AirCity场景不执行子元素冒泡上来的事件
            window.addEventListener("beforeunload", resetScene, false);
        }
      };
    };
    onMounted(() => {
      connectWebSocket();
    });
    onBeforeUnmount(() => {
      player && player.destroy();
      playerApi && playerApi.destroy();
      window.removeEventListener("resize", setPlayerOfWindowSize);
      window.removeEventListener("beforeunload", resetScene);
    });
    return {};
  },
};
</script>

<style lang="less" scoped>
#player {
  width: 100%;
  height: 100%;
  position: absolute;
  z-index: 0;
}
</style>
